package com.cls.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cls.business.entity.Message;
import com.cls.business.mapper.MessageMapper;
import com.cls.business.service.IMessageService;
import com.cls.common.entity.QueryRequest;
import com.cls.common.utils.RedisUtils;
import com.cls.common.websocket.WebSocketServer;
import com.cls.system.entity.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 系统消息表 Service实现
 *
 * @author wandering
 * @date 2020-11-27 10:39:09
 */
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements IMessageService {

    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisUtils redisUtils;
    private final WebSocketServer webSocketServer;


    @Override
    public PageInfo<Message> findMessages(QueryRequest request, Message message) {
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(message.getPublishUserId()).ifPresent(i -> queryWrapper.eq(Message::getPublishUserId, i));
        Optional.ofNullable(message.getReceiveUserId()).ifPresent(i -> queryWrapper.eq(Message::getReceiveUserId, i));
        queryWrapper.orderByDesc(Message::getCreateTime);
        // TODO 设置查询条件
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<Message> list = this.list(queryWrapper);
        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;
    }

    @Override
    public List<Message> findMessages(Message message) {
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 设置查询条件
        queryWrapper.orderByDesc(Message::getCreateTime);
        return this.baseMapper.selectList(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createMessage(Message message) {
        this.save(message);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMessage(Message message) {
        this.saveOrUpdate(message);
    }


    /**
     * 删除
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMessages(String[] ids) {
        List<String> list = Arrays.asList(ids);
        this.removeByIds(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendMessage(String messageText, User publishUser, User receiveUser) {
        Message message = setMessageInfo(messageText, publishUser);
        message.setReceiveUserId(receiveUser.getUserId());
        message.setReceiveObjectName(receiveUser.getUsername());
        message.setReceiveObjectUnitName(receiveUser.getDeptName());
        this.createMessage(message);
        webSocketServer.sendMessageTo(messageText, receiveUser.getUserId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendMessageById(String messageText, User publishUser, Long receiveUserId) {
        Message message = setMessageInfo(messageText, publishUser);
        message.setReceiveUserId(receiveUserId);
        this.createMessage(message);
        webSocketServer.sendMessageTo(messageText, receiveUserId);
    }

    public Message setMessageInfo(String messageText, User publishUser) {
        Message message = new Message();
        message.setContent(messageText);
        message.setPublishUserId(publishUser.getUserId());
        message.setPublishObjectName(publishUser.getUsername());
        message.setPublishObjectUnitName(publishUser.getDeptName());
        message.setSendTime(new Date());
        return message;
    }
}
